#include "includes.h"


char temp[10];


BOOL mcp_init()
{
	uint8_t value;

	mcp_reset(); 		// Send reset-kommando
	
	// Interrupt
    clear_bit(DDRE, DDE4);
	set_bit(EIMSK,INT4);
	set_bit(EICRB,ISC41);	

	// Self-test
	value = mcp_read_byte(MCP_CANSTAT);

	if ((value & MODE_MASK) != MODE_CONFIG)
	{
		USART_print("MCP2515 is NOT in configuration mode after reset!\r\n");
		return TRUE;
	}
	mcp_bit_modify(MCP_CANCTRL, MODE_NORMAL, MODE_MASK); // Set the CAN-controller to NORMAL mode
    mcp_bit_modify(CAN_INTE,((1<<CAN_RX0IE)|(1<<CAN_RX1IE)),((1<<CAN_RX0IE)|(1<<CAN_RX1IE)));

	value = mcp_read_byte(MCP_CANSTAT);

	if ((value & MODE_MASK) != MODE_NORMAL)
	{
		USART_print("MCP2515 is NOT in normal mode!\r\n");
		return TRUE;
	}
	return FALSE;
}


void mcp_reset()
{
	_delay_ms(1);
	enable_spi_transmission(MCP);
	_delay_ms(1);
	SPI_write(MCP_RESET);
	_delay_ms(1);
	disable_spi_transmission(MCP);
	_delay_ms(100);
}


uint8_t mcp_read_byte(uint8_t address)
{
	uint8_t result;
	enable_spi_transmission(MCP);	// Select CAN-controller
	SPI_write(MCP_READ);			// Send read command
	SPI_write(address);				// Send address
	SPI_write(address);				// Send address
	result = SPI_read();			// Read result
	disable_spi_transmission(MCP);	// Deselect CAN-controller
	return result;
}


void mcp_write_byte(uint8_t address, uint8_t data) 
{
	enable_spi_transmission(MCP);	// Select CAN-controller
	SPI_write(MCP_WRITE);			// Send write command
	SPI_write(address);				// Send address
	SPI_write(data);				// Send byte
	disable_spi_transmission(MCP);	// Deselect CAN-controller
}


void mcp_rts(uint8_t buffer)		// Request to send at buffer
{
	uint8_t rts;
	rts = (buffer|MCP_RTS);
	enable_spi_transmission(MCP);	// Select CAN-controller
	SPI_write(rts);					// Send RTS command
	disable_spi_transmission(MCP);	// Deselect CAN-controller
}


void mcp_bit_modify(uint8_t address, uint8_t data, uint8_t mask)
{
	enable_spi_transmission(MCP);	// Select CAN-controller
	SPI_write(MCP_BIT_MODIFY);		// Send bit modify command
	SPI_write(address);
	SPI_write(mask);				// Can change all bits
	SPI_write(data);
	disable_spi_transmission(MCP);	// Deselect CAN-controller
	
}


uint8_t mcp_read_status() 
{	
	uint8_t status;
	_delay_ms(1);
	enable_spi_transmission(MCP);	// Select CAN-controller
	_delay_ms(1);
	SPI_write(MCP_READ_STATUS);
	SPI_write(MCP_READ_STATUS);
	_delay_ms(1);
	status = SPI_read();
	_delay_ms(1);
	disable_spi_transmission(MCP);	// Deselect CAN-controller
	_delay_ms(1);
	return status;
}


uint8_t mcp_rx_status(void)
{
    uint8_t status;
    enable_spi_transmission(MCP);	// Select CAN-controller
    SPI_write(MCP_RX_STATUS);
    SPI_write(MCP_RX_STATUS);
    status = SPI_read();
    disable_spi_transmission(MCP);	// Deselect CAN-controller
	return status;
}
